import webpack, { RuleSetUseItem, Configuration, WebpackPluginInstance } from 'webpack';
import minCssExtractPlugin from 'mini-css-extract-plugin';
import LoadablePlugin from '@loadable/webpack-plugin';
import path from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import { WebpackManifestPlugin } from 'webpack-manifest-plugin';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

export const isDev = process.env.NODE_ENV === 'development'

// loader style-loader css-loader sass-loader postcss-loader

const getStyleLoaders = (isWeb: boolean, isSass?: boolean) => {
    let loaders: RuleSetUseItem[] = [
        {
            loader: 'css-loader',
            options: {
                importLoaders: isSass ? 2 : 1,
                modules: {
                    auto: true,
                    localIdentName: isDev ? '[path][name]__[local]' : '[hash:base64]',
                    exportOnlyLocals: !isWeb, // ssr
                }
            },
        },
        {
            loader: 'postcss-loader',
        },
        {
            loader: 'style-loader',
        },
    ]

    if (isWeb) {
        loaders = [
            ...loaders,
            minCssExtractPlugin,
        ]
    }

    if (isSass) {
        loaders = [
            ...loaders,
            {
                loader: 'sass-loader',
            },
        ]
    }

    return loaders
}
// plugins

const getPlugins = (isWeb: boolean) => {
    let plugins = [
        new webpack.ProgressPlugin(),
        // 适用于ssr 服务下的mainfest 信息
        new WebpackManifestPlugin({
            fileName: 'manifest.json',
            publicPath: '/',
            writeToFileEmit: true,
        }),


        new LoadablePlugin({
            writeToDisk: true,
            filename: '../loadable-stats.json',
        }),



        // 定义全局变量
        new webpack.DefinePlugin({
            __DEV__: isDev,
            __CLIENT__: isWeb,
            __SERVER__: !isWeb,
        }),
    ]

    if (isDev) {
        plugins = [
            ...plugins,
            new ForkTsCheckerWebpackPlugin({
                eslint: {
                    files: './src/**/*.{ts,tsx,js,jsx}',
                }
            })
        ]
    }
    // 根据 process.env.NODE_ENV analyze 
    if (!isDev) {
        plugins = [
            ...plugins,
            new BundleAnalyzerPlugin({
                analyzerMode: process.env.NODE_ENV === 'analyze' ? 'server' : 'disabled',
            }),
        ]
    }

    return plugins
}

const config = (isWeb = false): Configuration => ({
    mode: isDev ? 'development' : 'production',
    stats: 'minimal',
    context: path.resolve(process.cwd()),  // 默认是当前目录
    output: { clean: true },
    // 压缩大小
    optimization: {
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    compress: {
                        drop_console: true,
                    }
                }
            }),
        ]
    },
    plugins: getPlugins(isWeb) as WebpackPluginInstance[],
    module: {
        rules: [
            {
                test: /\.(t|j)sx?$/,
                exclude: /node_modules/,
                use: 'babel-loader',
                options: {
                    caller: {
                        target: isWeb ? 'web' : 'node',
                    },
                    cacheDirectory: true,
                }
            },
            {
                test: /\.css$/,
                use: getStyleLoaders(isWeb),
            },
            {
                test: /\.(scss|sass)$/,
                use: getStyleLoaders(isWeb, true),
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                type: 'asset',
                generator: {
                    emit: isWeb,
                }
            },
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset',
                generator: {
                    emit: isWeb,
                }

            }
        ]
    },

    resolve: {
        modules: ['src', 'node_modules'],
        extensions: ['.ts', '.tsx', '.js', '.jsx', '.json']
    }

})


export default config